package com.tanhua.sso.service;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tanhua.sso.config.AliyunSMSConfig;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Service
public class SmsService {

    private static Logger LOGGER = LoggerFactory.getLogger(SmsService.class);

    public static final String KEY = "CHECK_CODE_";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private AliyunSMSConfig aliyunSmsConfig;

    @Autowired
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 发送验证码
     *
     * @param mobile 手机号
     * @return code和msg的map集合
     */
    public Map<String, Object> sendCheckCode(String mobile) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            String redisKey = KEY + mobile;
            String value = this.redisTemplate.opsForValue().get(redisKey);
            if (StringUtils.isNotEmpty(value)) {
                result.put("code", 1);
                result.put("msg", "上一次发送的验证码还未失效");
                return result;
            }
            //String code = this.sendSms(mobile);
            String code = "123456";
            if (null == code) {
                result.put("code", 2);
                result.put("msg", "发送短信验证码失败");
                return result;
            }
            //发送验证码成功
            result.put("code", 3);
            result.put("msg", "ok");

            //将验证码存储到Redis,2分钟后失效
            this.redisTemplate.opsForValue().set(redisKey, code, Duration.ofMinutes(2));

            return result;
        } catch (Exception e) {

            LOGGER.error("发送验证码出错！" + mobile, e);

            result.put("code", 4);
            result.put("msg", "发送验证码出现异常");
            return result;
        }
    }

    /**
     * 发送短信
     *
     * @param phone 手机号
     * @return 验证码
     */
    public String sendSms(String phone) {
        // 生成6位随机数
        int code = RandomUtils.nextInt(100000, 999999);

        // 设置超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化acsClient
        DefaultProfile profile = DefaultProfile.getProfile(
                aliyunSmsConfig.getRegionId(),
                aliyunSmsConfig.getAccessKeyId(),
                aliyunSmsConfig.getAccessKeySecret());
        DefaultProfile.addEndpoint(
                "cn-hangzhou",
                aliyunSmsConfig.getProduct(),
                aliyunSmsConfig.getDomain());
        IAcsClient client = new DefaultAcsClient(profile);
        //组装请求对象
        SendSmsRequest request = new SendSmsRequest();
        //请求方式：post
        request.setSysMethod(MethodType.POST);
        //待发送手机号
        request.setPhoneNumbers(phone);
        //短信签名
        request.setSignName(aliyunSmsConfig.getSignName());

        //短信模板code
        request.setTemplateCode(aliyunSmsConfig.getTemplateCode());
        //模板内容${code}参数值
        request.setTemplateParam("{\"code\":\"" + code + "\"}");

        SendSmsResponse sendSmsResponse;
        try {
            sendSmsResponse = client.getAcsResponse(request);
            sendSmsResponse.setBizId(String.valueOf(code));
            // 响应状态，ok代表发送成功
            String status = sendSmsResponse.getCode();
            if ("OK".equals(status)) {
                return sendSmsResponse.getBizId();
            }
        } catch (Exception e) {
            LOGGER.info(e.getMessage());
        }
        return null;
    }
}
